<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>电子相册系统 · 汇报 Demo（整合版）</title>
<!-- 源需求文档（本地）: /mnt/data/电子相册系统面向对象需求分析 (1).docx -->

</head>
<body>

<!-- 相册 modal -->
<div id="albumModal" class="hidden" role="dialog" aria-modal="true" aria-hidden="true">
  <div class="overlay" onclick="overlayClick(event)">
    <div class="modal" onclick="event.stopPropagation()">
      <div class="left">
        <button class="nav-btn nav-left" onclick="prevPhoto()">‹</button>
        <img id="modalImage" src="" alt="相册图片" />
        <button class="nav-btn nav-right" onclick="nextPhoto()">›</button>
      </div>
      <div class="right">
        <div><div class="title" id="modalTitle">相册标题</div><div class="muted" id="modalAuthor">作者</div></div>

        <div class="stats">
          <div><div class="stat-num" id="modalLikeCount">0 ❤️</div><div class="muted" id="modalFavCount">0 收藏</div></div>
          <div style="text-align:right">
            <button class="btn ghost" id="modalLikeBtn" onclick="modalToggleLike()">👍 点赞</button>
            <button class="btn ghost" id="modalFavBtn" onclick="modalToggleFav()">⭐ 收藏</button>
          </div>
        </div>

        <div class="comments" id="commentsList" aria-live="polite"></div>

        <div class="comment-box">
          <input id="commentInput" placeholder="写评论..." />
          <button class="btn" id="commentSend" onclick="sendComment()">发送</button>
        </div>

        <div style="margin-top:8px;text-align:right">
          <button class="btn ghost" onclick="addPhotoToCurrentAlbum()">➕ 上传照片</button>
          <button class="btn ghost" onclick="closeModal()">关闭</button>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- 创建相册页面（图形化） -->
<div id="createAlbumView" class="page hidden">
  <div class="auth-center" style="max-width:520px;">
    <h1>创建相册</h1>
    <p class="muted">填写相册信息并上传图片 URL</p>

    <div class="field"><label class="muted">相册标题</label><input id="newAlbumTitle" placeholder="如：海边旅行" /></div>
    <div class="field"><label class="muted">类别</label><input id="newAlbumCategory" placeholder="如：旅行、美食..." /></div>
    <div class="field"><label class="muted">封面图片 URL</label><input id="newAlbumCover" placeholder="输入封面图片链接" /></div>

    <div id="newPhotosArea"></div>

    <button class="btn ghost" onclick="addPhotoField()">添加一张图片 URL</button>

    <div style="display:flex;gap:10px;margin-top:20px;">
      <button class="btn" onclick="submitNewAlbum()">创建</button>
      <button class="btn ghost" onclick="showView('mainView')">返回主页</button>
    </div>
  </div>
</div>

<!-- 个人主页 -->
<div id="profileView" class="page hidden">
  <div class="profile-wrap">
    <div class="profile-card">
      <div class="profile-avatar" id="profileAvatar">U</div>
      <div style="font-weight:800" id="profileName">用户名</div>
      <div class="muted" id="profileSince">注册时间</div>
      <div style="width:100%;display:flex;gap:8px;margin-top:8px">
        <button class="btn" onclick="saveProfile()">保存修改</button>
        <button class="btn ghost" onclick="showView('mainView')">返回</button>
      </div>
      <div style="width:100%;margin-top:10px">
        <button class="btn ghost" style="width:100%" onclick="logout()">登出</button>
        <button class="btn" style="width:100%;margin-top:8px;background:#f87171" onclick="deleteAccount()">注销账户（删除）</button>
      </div>
    </div>

    <div>
      <div class="profile-info card">
        <h3>账号信息</h3>
        <label>用户名</label><input id="editUsername" />
        <label>密码</label><input id="editPassword" type="password" placeholder="不改请留空" />
        <label>个人签名</label><input id="editBio" placeholder="一句话介绍自己" />
      </div>

      <div class="card" style="margin-top:12px">
        <h3>统计</h3>
        <div style="display:flex;gap:12px;margin-top:8px">
          <div><strong id="statAlbums">0</strong><div class="muted">相册</div></div>
          <div><strong id="statLikes">0</strong><div class="muted">获赞</div></div>
          <div><strong id="statFavs">0</strong><div class="muted">收藏</div></div>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- 管理员登录 -->
<div id="adminLoginView" class="page hidden">
  <div class="auth-center">
    <h1>管理员登录</h1>
    <p class="muted">演示：admin / admin</p>
    <div class="field"><input id="adminUser" placeholder="admin"></div>
    <div class="field"><input id="adminPwd" type="password" placeholder="admin"></div>
    <div style="display:flex;gap:8px">
      <button class="btn" onclick="adminLogin()">登录</button>
      <button class="btn ghost" onclick="showView('loginView')">返回</button>
    </div>
  </div>
</div>

<!-- 管理员后台 -->
<div id="adminView" class="page hidden">
  <div class="admin-panel">
    <div style="display:flex;justify-content:space-between;align-items:center">
      <h2>管理员后台</h2>
      <div><button class="btn ghost" onclick="adminLogout()">退出管理员</button></div>
    </div>

    <div style="display:flex;gap:12px;margin-top:12px">
      <div style="flex:1">
        <h3>用户管理</h3>
        <div style="display:flex;gap:8px;margin-bottom:8px;">
          <button class="btn ghost" onclick="openAdminUsers()">查看用户</button>
          <button class="btn ghost" onclick="openAdminPhotos()">管理图片</button>
          <button class="btn ghost" onclick="openAdminComments()">管理评论</button>
        </div>
        <div id="userTable" style="margin-top:8px"></div>
      </div>

      <div style="width:360px">
        <h3>类别管理</h3>
        <div style="display:flex;gap:8px">
          <input id="catInput" class="field" placeholder="新增类别">
          <button class="btn" onclick="addCategory()">添加</button>
        </div>
        <div class="cat-list" id="catList" style="margin-top:10px"></div>

        <h3 style="margin-top:12px">相册管理</h3>
        <div id="adminAlbumList" style="margin-top:8px"></div>
      </div>
    </div>
  </div>
</div>

<!-- 管理：删除图片视图 -->
<div id="adminPhotosView" class="page hidden">
  <div class="admin-panel">
    <h2>删除相册图片</h2>
    <select id="adminPhotoAlbumSelect" onchange="loadAdminPhotos()"></select>
    <div id="adminPhotosList" style="margin-top:14px;"></div>
    <button class="btn ghost" onclick="showView('adminView')">返回后台</button>
  </div>
</div>

<!-- 管理：删除评论视图 -->
<div id="adminCommentsView" class="page hidden">
  <div class="admin-panel">
    <h2>删除评论</h2>
    <select id="adminCommentAlbumSelect" onchange="loadAdminComments()"></select>
    <div id="adminCommentsList" style="margin-top:14px;"></div>
    <button class="btn ghost" onclick="showView('adminView')">返回后台</button>
  </div>
</div>

<!-- 管理：用户封禁视图 -->
<div id="adminUsersView" class="page hidden">
  <div class="admin-panel">
    <h2>用户管理 · 封禁/解封</h2>
    <div id="adminUsersList"></div>
    <button class="btn ghost" onclick="showView('adminView')">返回后台</button>
  </div>
</div>
<script>
/* ========== 初始示例数据（不持久化） ========== */
const SAMPLE = [
  { id:'a1', title:'海边的夏天', author:'demo', category:'旅行',
    cover:'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=1200&auto=format&fit=crop',
    photos:['https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=1400&auto=format&fit=crop','https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?q=80&w=1400&auto=format&fit=crop'],
    likes:['alice'], favorites:[], comments:[{user:'alice',text:'美极了',ts:Date.now()-3600*1000}]
  },
  { id:'a2', title:'城市日常', author:'bob', category:'生活',
    cover:'https://images.unsplash.com/photo-1499346030926-9a72daac6c63?q=80&w=1200&auto=format&fit=crop',
    photos:['https://images.unsplash.com/photo-1499346030926-9a72daac6c63?q=80&w=1400&auto=format&fit=crop'],
    likes:[], favorites:['demo'], comments:[]
  },
  { id:'a3', title:'美食笔记', author:'carol', category:'美食',
    cover:'https://images.unsplash.com/photo-1504674900247-0877df9cc836?q=80&w=1200&auto=format&fit=crop',
    photos:['https://images.unsplash.com/photo-1504674900247-0877df9cc836?q=80&w=1400&auto=format&fit=crop'],
    likes:[], favorites:[], comments:[]
  }
];

let data = {
  users:[
    { username:'demo', password:'1234', bio:'Hello! 我是 demo', created:Date.now()-86400*1000, banned:false },
    { username:'alice', password:'2222', bio:'摄影爱好者', created:Date.now()-86400*200, banned:false },
    { username:'bob', password:'2222', bio:'城市记录', created:Date.now()-86400*300, banned:false },
    { username:'carol', password:'3333', bio:'美食收藏家', created:Date.now()-86400*500, banned:false }
  ],
  albums: JSON.parse(JSON.stringify(SAMPLE)),
  categories:['全部','旅行','生活','美食'],
  admin:{user:'admin',pwd:'admin'}
};

let ui = { currentUser:null, currentAlbumId:null, currentPhotoIndex:0 };

/* ---------- 简单视图切换 ---------- */
function showView(id){
  document.querySelectorAll('.page').forEach(p=>p.classList.add('hidden'));
  document.getElementById(id).classList.remove('hidden');
}

/* ---------- 注册 / 登录 / 注销 ---------- */
function register(){
  const u = document.getElementById('regUser').value.trim();
  const p = document.getElementById('regPwd').value.trim();
  if(!u||!p) return alert('请输入用户名和密码');
  if(data.users.find(x=>x.username===u)) return alert('用户名已存在');
  data.users.push({username:u,password:p,bio:'',created:Date.now(),banned:false});
  ui.currentUser = u;
  afterLogin();
}
document.getElementById('loginBtn').addEventListener('click', ()=>{
  const u = document.getElementById('loginUser').value.trim();
  const p = document.getElementById('loginPwd').value.trim();
  const user = data.users.find(x=>x.username===u && x.password===p);
  if(!user) return alert('账号或密码错误（演示：demo / 1234）');
  if(user.banned) return alert('该账户已被封禁，无法登录。');
  ui.currentUser = u;
  afterLogin();
});
function logout(){ ui.currentUser = null; showView('loginView'); }
function afterLogin(){
  document.getElementById('userName').textContent = ui.currentUser;
  document.getElementById('userAvatar').textContent = ui.currentUser.charAt(0).toUpperCase();
  renderCategories(); renderAlbums(); showView('mainView'); updateProfileStats();
}

/* ---------- Categories ---------- */
function renderCategories(){
  const el = document.getElementById('categories'); el.innerHTML='';
  data.categories.forEach(cat=>{
    const d = document.createElement('div'); d.className='chip'+(cat==='全部'?' active':''); d.textContent=cat;
    d.onclick = ()=>{ document.querySelectorAll('.chip').forEach(c=>c.classList.remove('active')); d.classList.add('active'); renderAlbums(); };
    el.appendChild(d);
  });
}

/* ---------- Albums rendering ---------- */
function renderAlbums(){
  const grid = document.getElementById('albumGrid'); grid.innerHTML='';
  const q = (document.getElementById('searchInput').value||'').trim().toLowerCase();
  const activeChip = Array.from(document.querySelectorAll('.chip')).find(c=>c.classList.contains('active'));
  const activeCat = activeChip ? activeChip.textContent : '全部';
  const albums = data.albums.filter(a=>{
    const inCat = activeCat==='全部' || a.category===activeCat;
    const inQ = !q || a.title.toLowerCase().includes(q) || a.author.toLowerCase().includes(q);
    return inCat && inQ;
  });
  if(albums.length===0){ grid.innerHTML='<div style="color:var(--muted);padding:18px">无匹配相册</div>'; return; }
  albums.forEach(a=>{
    const card = document.createElement('div'); card.className='album-card';
    card.innerHTML=`<img src="${a.cover}" alt="${escapeHtml(a.title)}"/><div class="meta"><div class="title">${escapeHtml(a.title)}</div><div class="info">by ${escapeHtml(displayAuthor(a.author))} · ${a.photos.length} 张 · ${escapeHtml(a.category)}</div></div>`;
    card.onclick = ()=>openAlbumModal(a.id);
    grid.appendChild(card);
  });
}

/* helper */
function displayAuthor(name){
  const u = data.users.find(x=>x.username===name);
  if(!u) return name || '已删除用户';
  if(u.banned) return name + ' (已封禁)';
  return name;
}

/* ---------- Create album (prompt & form) ---------- */
function createAlbumPrompt(){
  if(!ui.currentUser) return alert('请先登录');
  const title = prompt('相册标题'); if(!title) return;
  const category = prompt('类别 (如旅行/美食/生活)', '未分类') || '未分类';
  const id = 'a' + Date.now();
  const newAlbum = { id, title, author: ui.currentUser, category, cover:'https://via.placeholder.com/800x600?text=封面', photos:[], likes:[], favorites:[], comments:[] };
  data.albums.unshift(newAlbum);
  if(!data.categories.includes(category)) data.categories.push(category);
  renderCategories(); renderAlbums(); updateProfileStats();
}

/* form-based create */
function addPhotoField(){
  const area = document.getElementById('newPhotosArea');
  const input = document.createElement('input'); input.placeholder='图片 URL'; input.style='width:100%;margin:6px 0;padding:10px;border-radius:10px;border:1px solid #ddd;';
  area.appendChild(input);
}
function submitNewAlbum(){
  if(!ui.currentUser) return alert('请先登录');
  const title = document.getElementById('newAlbumTitle').value.trim();
  const cat = document.getElementById('newAlbumCategory').value.trim();
  const cover = document.getElementById('newAlbumCover').value.trim();
  if(!title||!cat||!cover) return alert('请填写完整信息');
  const photos = Array.from(document.querySelectorAll('#newPhotosArea input')).map(i=>i.value.trim()).filter(Boolean);
  const id='a'+Date.now();
  const alb={ id,title,author:ui.currentUser,category:cat,cover,photos,likes:[],favorites:[],comments:[] };
  data.albums.unshift(alb);
  if(!data.categories.includes(cat)) data.categories.push(cat);
  renderCategories(); renderAlbums(); showView('mainView'); updateProfileStats();
}

/* ---------- Modal: open/close/update ---------- */
function openAlbumModal(albumId){
  const album = data.albums.find(a=>a.id===albumId); if(!album) return;
  ui.currentAlbumId = albumId; ui.currentPhotoIndex = 0; updateModal();
  document.getElementById('albumModal').classList.remove('hidden'); document.getElementById('albumModal').setAttribute('aria-hidden','false');
}
function closeModal(){ ui.currentAlbumId=null; document.getElementById('albumModal').classList.add('hidden'); document.getElementById('albumModal').setAttribute('aria-hidden','true'); }
function overlayClick(e){ if(e.target.classList.contains('overlay')) closeModal(); }
function updateModal(){
  const album = data.albums.find(a=>a.id===ui.currentAlbumId); if(!album) return;
  const idx = ui.currentPhotoIndex; const src = album.photos.length ? (album.photos[idx]||album.cover) : album.cover;
  document.getElementById('modalImage').src = src;
  document.getElementById('modalTitle').textContent = album.title;
  document.getElementById('modalAuthor').textContent = 'by ' + displayAuthor(album.author);
  document.getElementById('modalLikeCount').textContent = album.likes.length + ' ❤️';
  document.getElementById('modalFavCount').textContent = album.favorites.length + ' 收藏';
  const comments = document.getElementById('commentsList'); comments.innerHTML='';
  (album.comments||[]).slice().reverse().forEach(c=>{
    const div=document.createElement('div'); div.className='comment';
    div.innerHTML = `<strong>${escapeHtml(c.user)}</strong><div class="txt">${escapeHtml(c.text)}</div><div class="muted" style="font-size:11px;margin-top:6px">${timeAgo(c.ts)}</div>`;
    comments.appendChild(div);
  });
}

/* prev/next */
function prevPhoto(){ const album=data.albums.find(a=>a.id===ui.currentAlbumId); if(!album||album.photos.length===0)return; ui.currentPhotoIndex=(ui.currentPhotoIndex-1+album.photos.length)%album.photos.length; updateModal(); }
function nextPhoto(){ const album=data.albums.find(a=>a.id===ui.currentAlbumId); if(!album||album.photos.length===0)return; ui.currentPhotoIndex=(ui.currentPhotoIndex+1)%album.photos.length; updateModal(); }

/* modal actions */
function modalToggleLike(){ if(!ui.currentUser) return alert('请先登录'); const album=data.albums.find(a=>a.id===ui.currentAlbumId); if(!album) return; const me=ui.currentUser; const idx=album.likes.indexOf(me); if(idx>=0) album.likes.splice(idx,1); else album.likes.push(me); updateModal(); renderAlbums(); updateProfileStats(); }
function modalToggleFav(){ if(!ui.currentUser) return alert('请先登录'); const album=data.albums.find(a=>a.id===ui.currentAlbumId); if(!album) return; const me=ui.currentUser; const idx=album.favorites.indexOf(me); if(idx>=0) album.favorites.splice(idx,1); else album.favorites.push(me); updateModal(); renderAlbums(); updateProfileStats(); }
function sendComment(){ if(!ui.currentUser) return alert('请先登录'); const txt=document.getElementById('commentInput').value.trim(); if(!txt) return; const album=data.albums.find(a=>a.id===ui.currentAlbumId); if(!album) return; album.comments.push({user:ui.currentUser,text:txt,ts:Date.now()}); document.getElementById('commentInput').value=''; updateModal(); renderAlbums(); updateProfileStats(); }

/* add photo via URL to current album (modal) */
function addPhotoToCurrentAlbum(){ if(!ui.currentUser) return alert('请先登录'); const url=prompt('请输入图片 URL'); if(!url) return; const album=data.albums.find(a=>a.id===ui.currentAlbumId); if(!album) return; album.photos.push(url); if(!album.cover||album.cover.includes('placeholder')) album.cover=url; updateModal(); renderAlbums(); updateProfileStats(); }

/* ---------- Profile (卡片式) ---------- */
function showProfile(){
  if(!ui.currentUser) return alert('请先登录');
  const user = data.users.find(u=>u.username===ui.currentUser);
  if(!user) return alert('用户数据异常');
  document.getElementById('profileAvatar').textContent = ui.currentUser.charAt(0).toUpperCase();
  document.getElementById('profileName').textContent = ui.currentUser;
  document.getElementById('profileSince').textContent = '注册于 ' + new Date(user.created).toLocaleDateString();
  document.getElementById('editUsername').value = user.username;
  document.getElementById('editPassword').value = '';
  document.getElementById('editBio').value = user.bio || '';
  updateProfileStats();
  showView('profileView');
}
function saveProfile(){
  const newName = document.getElementById('editUsername').value.trim();
  const newPwd = document.getElementById('editPassword').value.trim();
  const newBio = document.getElementById('editBio').value.trim();
  if(!newName) return alert('用户名不能为空');
  if(newName !== ui.currentUser && data.users.find(u=>u.username===newName)) return alert('用户名已存在');
  const user = data.users.find(u=>u.username===ui.currentUser);
  if(!user) return alert('用户不存在');
  if(newName !== ui.currentUser){
    data.albums.forEach(alb=>{ if(alb.author===ui.currentUser) alb.author = newName; alb.comments.forEach(c=>{ if(c.user===ui.currentUser) c.user = newName; }); alb.likes = alb.likes.map(x=> x===ui.currentUser ? newName : x); alb.favorites = alb.favorites.map(x=> x===ui.currentUser ? newName : x); });
  }
  user.username = newName; if(newPwd) user.password = newPwd; user.bio = newBio;
  ui.currentUser = newName;
  afterLogin();
  alert('保存成功');
}
function deleteAccount(){
  if(!confirm('确认注销账户？将删除账户与该账户的所有相册（演示环境）')) return;
  data.albums = data.albums.filter(a=> a.author !== ui.currentUser);
  data.users = data.users.filter(u=> u.username !== ui.currentUser);
  ui.currentUser = null; showView('loginView'); renderAlbums(); alert('账户及相册已删除（演示）');
}
function updateProfileStats(){
  if(!ui.currentUser){ document.getElementById('statAlbums').textContent=0; document.getElementById('statLikes').textContent=0; document.getElementById('statFavs').textContent=0; return; }
  const myAlbums = data.albums.filter(a=>a.author===ui.currentUser).length;
  const myLikes = data.albums.reduce((s,a)=> s + (a.likes.includes(ui.currentUser)?1:0), 0);
  const myFavs = data.albums.reduce((s,a)=> s + (a.favorites.includes(ui.currentUser)?1:0), 0);
  document.getElementById('statAlbums').textContent = myAlbums;
  document.getElementById('statLikes').textContent = myLikes;
  document.getElementById('statFavs').textContent = myFavs;
}

/* ---------- Admin: login/logout, render ---------- */
function adminLogin(){
  const u = document.getElementById('adminUser').value.trim();
  const p = document.getElementById('adminPwd').value.trim();
  if(u===data.admin.user && p===data.admin.pwd){ showView('adminView'); renderAdminUsers(); renderCatList(); renderAdminAlbums(); } else alert('管理员账号或密码错误');
}
function adminLogout(){ showView('loginView'); }

/* admin users table */
function renderAdminUsers(){
  const table = document.getElementById('userTable'); table.innerHTML='';
  data.users.forEach((u,i)=>{
    const div=document.createElement('div'); div.className='card'; div.style.marginBottom='8px';
    div.innerHTML = `<div style="display:flex;justify-content:space-between;align-items:center"><div><strong>${escapeHtml(u.username)}</strong><div class="muted">注册：${new Date(u.created).toLocaleDateString()}</div></div><div style="text-align:right"><div>${u.banned?'<span style="color:#f87171;font-weight:700">已封禁</span>':'正常'}</div><div style="margin-top:8px"><button class="btn ghost" onclick="toggleBan(${i})">${u.banned? '解封':'封禁'}</button> <button class="btn ghost" onclick="deleteUser(${i})" style="margin-left:6px">删除</button></div></div></div>`;
    table.appendChild(div);
  });
}

/* toggle ban (安全模式 A) */
function toggleBan(index){
  const user = data.users[index];
  if(!user) return;
  user.banned = !user.banned;
  renderAdminUsers();
  alert(user.banned? `${user.username} 已被封禁` : `${user.username} 已解封`);
}

/* admin delete user (soft behaviour) */
function deleteUser(index){
  const u = data.users[index]; if(!u) return;
  if(!confirm('确定删除用户 '+u.username+'？其相册将保留，作者会标注为 已删除用户')) return;
  const username = u.username;
  data.users.splice(index,1);
  data.albums.forEach(a=>{ if(a.author===username) a.author='已删除用户'; a.comments.forEach(c=>{ if(c.user===username) c.user='已删除用户'; }); a.likes = a.likes.filter(x=>x!==username); a.favorites = a.favorites.filter(x=>x!==username); });
  renderAdminUsers(); renderAlbums(); alert('删除完成');
}

/* categories admin */
function addCategory(){ const v=document.getElementById('catInput').value.trim(); if(!v) return alert('请输入类别名'); if(!data.categories.includes(v)) data.categories.push(v); renderCatList(); renderCategories(); }
function renderCatList(){ const el=document.getElementById('catList'); el.innerHTML=''; data.categories.forEach((c,i)=>{ if(c==='全部') return; const pill=document.createElement('div'); pill.className='cat-pill'; pill.innerHTML=`${escapeHtml(c)} <button class="btn ghost" style="margin-left:8px" onclick="delCategory(${i})">删除</button>`; el.appendChild(pill); }); }
function delCategory(i){ const name=data.categories[i]; if(!confirm('删除类别 '+name+'？')) return; data.categories.splice(i,1); renderCatList(); renderCategories(); }

/* admin album list */
function renderAdminAlbums(){ const el=document.getElementById('adminAlbumList'); el.innerHTML=''; data.albums.forEach((a,i)=>{ const div=document.createElement('div'); div.className='card'; div.style.marginBottom='8px'; div.innerHTML=`<div style="display:flex;justify-content:space-between;align-items:center"><div><strong>${escapeHtml(a.title)}</strong><div class="muted">by ${escapeHtml(a.author)}</div></div><div><button class="btn ghost" onclick="adminViewAlbum(${i})">查看</button></div></div>`; el.appendChild(div); }); }
function adminViewAlbum(index){ const alb = data.albums[index]; if(!alb) return; ui.currentAlbumId = alb.id; ui.currentPhotoIndex = 0; updateModal(); // append admin controls
  const comments = document.getElementById('commentsList'); comments.innerHTML=''; alb.comments.slice().reverse().forEach((c,ri)=>{ const realIndex = alb.comments.length-1-ri; const div=document.createElement('div'); div.className='comment'; div.innerHTML=`<strong>${escapeHtml(c.user)}</strong><div class="txt">${escapeHtml(c.text)}</div><div class="muted" style="font-size:11px;margin-top:6px">${timeAgo(c.ts)}</div><div style="margin-top:6px"><button class="btn ghost" onclick="adminDeleteComment('${alb.id}',${realIndex})">删除评论</button></div>`; comments.appendChild(div); });
  const right = document.querySelector('.modal .right'); const existing = document.getElementById('adminPhotoList'); if(existing) existing.remove();
  const adminPhotoList = document.createElement('div'); adminPhotoList.id='adminPhotoList'; adminPhotoList.innerHTML='<h4>照片管理（管理员）</h4>';
  alb.photos.forEach((p,pi)=>{ const item=document.createElement('div'); item.style.display='flex'; item.style.justifyContent='space-between'; item.style.alignItems='center'; item.style.marginBottom='6px'; item.innerHTML=`<div style="font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:200px">${p}</div><div><button class="btn ghost" onclick="adminDeletePhoto('${alb.id}',${pi})">删除图片</button></div>`; adminPhotoList.appendChild(item); });
  right.insertBefore(adminPhotoList, comments);
  document.getElementById('albumModal').classList.remove('hidden'); document.getElementById('albumModal').setAttribute('aria-hidden','false');
}
function adminDeleteComment(albumId, commentIndex){ const alb = data.albums.find(a=>a.id===albumId); if(!alb) return; if(!confirm('确认删除该评论？')) return; alb.comments.splice(commentIndex,1); alert('评论已删除'); renderAdminAlbums(); renderAlbums(); if(ui.currentAlbumId===albumId) adminViewAlbum(data.albums.findIndex(a=>a.id===albumId)); }
function adminDeletePhoto(albumId, photoIndex){ const alb = data.albums.find(a=>a.id===albumId); if(!alb) return; if(!confirm('确认删除该图片？')) return; alb.photos.splice(photoIndex,1); if(!alb.photos.length) alb.cover='https://via.placeholder.com/800x600?text=封面'; else alb.cover=alb.photos[0]; alert('图片已删除'); renderAdminAlbums(); renderAlbums(); if(ui.currentAlbumId===albumId) adminViewAlbum(data.albums.findIndex(a=>a.id===albumId)); }

/* admin open specific admin views */
function openAdminPhotos(){ const sel=document.getElementById('adminPhotoAlbumSelect'); sel.innerHTML=data.albums.map(a=>`<option value="${a.id}">${escapeHtml(a.title)}</option>`).join(''); loadAdminPhotos(); showView('adminPhotosView'); }
function loadAdminPhotos(){ const id=document.getElementById('adminPhotoAlbumSelect').value; const alb=data.albums.find(a=>a.id===id); const list=document.getElementById('adminPhotosList'); list.innerHTML = alb.photos.map((p,i)=>`<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;"><img src="${p}" style="width:80px;height:60px;object-fit:cover;border-radius:8px;"><button class="admin-mini-btn" onclick="delPhoto('${id}',${i})">删除</button></div>`).join(''); }
function delPhoto(id,index){ const alb=data.albums.find(a=>a.id===id); if(!confirm('删除图片？')) return; alb.photos.splice(index,1); loadAdminPhotos(); renderAlbums(); }

/* admin comments view */
function openAdminComments(){ const sel=document.getElementById('adminCommentAlbumSelect'); sel.innerHTML=data.albums.map(a=>`<option value="${a.id}">${escapeHtml(a.title)}</option>`).join(''); loadAdminComments(); showView('adminCommentsView'); }
function loadAdminComments(){ const id=document.getElementById('adminCommentAlbumSelect').value; const alb=data.albums.find(a=>a.id===id); const list=document.getElementById('adminCommentsList'); list.innerHTML = alb.comments.map((c,i)=>`<div style="padding:8px;border-bottom:1px dashed #ddd;"><strong>${escapeHtml(c.user)}</strong>：${escapeHtml(c.text)}<button class="admin-mini-btn" onclick="delAdminComment('${id}',${i})">删除</button></div>`).join(''); }
function delAdminComment(id,idx){ const alb=data.albums.find(a=>a.id===id); alb.comments.splice(idx,1); loadAdminComments(); renderAlbums(); }

/* admin users view */
function openAdminUsers(){ const box=document.getElementById('adminUsersList'); box.innerHTML = data.users.map(u=>`<div style="padding:10px;border-bottom:1px dashed #ddd;display:flex;justify-content:space-between;"><span>${escapeHtml(u.username)} ${u.banned?'<strong style="color:#f87171">(已封禁)</strong>':''}</span><div><button class="admin-mini-btn" onclick="toggleBan('${escapeHtml(u.username)}')">${u.banned?'解封':'封禁'}</button></div></div>`).join(''); showView('adminUsersView'); }
function toggleBan(name){ const u=data.users.find(x=>x.username===name); if(!u) return; u.banned=!u.banned; openAdminUsers(); alert(u.banned?`${u.username} 已被封禁`:`${u.username} 已解封`); }

/* helpers */
function escapeHtml(str){ return String(str||'').replace(/[&<>"']/g,(m)=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m])); }
function timeAgo(ts){ const s=Math.floor((Date.now()-ts)/1000); if(s<60) return s+' 秒前'; if(s<3600) return Math.floor(s/60)+' 分钟前'; if(s<86400) return Math.floor(s/3600)+' 小时前'; return Math.floor(s/86400)+' 天前'; }

/* init */
(function init(){ data.albums.forEach(a=>{ if(!a.id) a.id='a'+Date.now()+Math.random(); }); showView('loginView'); document.getElementById('loginUser').value='demo'; document.getElementById('loginPwd').value='1234'; })();
</script>
</body>
</html>
